#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
#define Fi first
#define Se second
using namespace std;
const int maxn=1e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
pair< pair<LL,LL>, pair<LL,LL> >a[maxn];
bool cmp(pair< pair<LL,LL>, pair<LL,LL> > A,pair< pair<LL,LL>, pair<LL,LL> > B){
     return A.Fi.Fi<B.Fi.Fi;
}
struct Node{
    LL st,ed,id;
};
bool operator <(const Node& A,const Node& B){
         return A.ed>B.ed;
}
LL cnt=0;
LL solve(LL n){
    multiset<LL>mi,mx;
    priority_queue<Node>que;
    sort(a+1,a+1+n,cmp);
    for(LL i=1;i<=n;i++){
        while(!que.empty()&&que.top().ed<a[i].Fi.Fi){
              LL id=que.top().id;
              que.pop();
              mi.erase(a[id].Se.Se);
              mx.erase(a[id].Se.Fi);
        }
        if(!mi.empty()&&(*mi.begin())<a[i].Se.Fi) return 0;
        if(!mx.empty()&&(*mx.rbegin())>a[i].Se.Se) return 0;
        mi.insert(a[i].Se.Se);
        mx.insert(a[i].Se.Fi);
        que.push({a[i].Fi.Fi,a[i].Fi.Se,i});
    }
    return 1;
}
int main(void){
   cin.tie(0);std::ios::sync_with_stdio(false);
   LL n;cin>>n;
   for(LL i=1;i<=n;i++){
       cin>>a[i].Fi.Fi>>a[i].Fi.Se;
       cin>>a[i].Se.Fi>>a[i].Se.Se;
   }
   LL flag=1;
   flag=min(solve(n),flag);
   for(LL i=1;i<=n;i++){
      LL xx=a[i].Fi.Fi;
      LL yy=a[i].Fi.Se;
      a[i].Fi.Fi=a[i].Se.Fi;a[i].Fi.Se=a[i].Se.Se;
      a[i].Se.Fi=xx;a[i].Se.Se=yy;
   }
   flag=min(solve(n),flag);
   if(flag){
      cout<<"YES"<<"\n";
   }
   else{
       cout<<"NO"<<"\n";
   }
   return 0;
}
